package com.ruoyi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.lzhpo.chatgpt.OpenAiClient;
import com.lzhpo.chatgpt.entity.embeddings.EmbeddingRequest;
import com.lzhpo.chatgpt.entity.embeddings.EmbeddingResponse;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.domain.GoogleSearchItem;
import com.ruoyi.domain.GoogleSearchResponse;
import com.ruoyi.service.IChatService;
import com.ruoyi.util.DistanceUtil;
import com.ruoyi.util.FileEmbedding;
import com.ruoyi.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author chenchuan2
 * @date 2023-05-07 23:36:31
 */
@Service
@Slf4j
@Order(99)
public class ChatServiceImpl implements IChatService {

    private static String DEFAULT_SEARCH_MSG = "你可以参考如下的一些数据来辅助回答问题，";

    private static String INNER_MSG = "你是个乐于助人的助手。当给出上下文时，你只使用这些信息来回答问题，并且你总是用markdown来格式化你的输出。如果相关，可以精简一下内容。如果你不确定，并且答案没有明确写在提供的上下文中，你会说“对不起，我不知道如何帮助你。”如果上下文中包含章节和条目，请在你的回复末尾的**SOURCE**标题下包含章节和条目，格式：第几章第几条。始终包括上下文中的章节和条目，但永远不要多次列出一个章节和条目。永远不要包含不在上下文部分中的章节和条目。从不编章节和条目 `；  上下文:{0}";

    public static List<FileEmbedding> FILE_EMBEDDING = Lists.newArrayList();

    private static String FILE_PATH = "/Users/chenchuan/Downloads/chatgpt/kaoqin.txt";

    @Autowired
    private OpenAiClient openAiClient;

//    @PostConstruct
//    public void init() {
//        List<String> strings = FileUtil.readFile(FILE_PATH);
//        List<FileEmbedding> convert = FileUtil.convert(strings);
//        for (FileEmbedding fileEmbedding : convert) {
//            EmbeddingRequest request = EmbeddingRequest.builder()
//                    .model("text-embedding-ada-002")
//                    .input(Lists.newArrayList(fileEmbedding.getContent())).build();
//            EmbeddingResponse embeddings = openAiClient.embeddings(request);
//            List<BigDecimal> embedding = embeddings.getData().get(0).getEmbedding();
//            fileEmbedding.setEmbeddings(embedding);
//        }
//        FILE_EMBEDDING = convert;
//    }

    @Override
    public String searchResult(String qa) {
        String s = HttpUtils.sendGet(parseUrl(qa));
        GoogleSearchResponse googleSearchResponse = JSONObject.parseObject(s, GoogleSearchResponse.class);
        List<GoogleSearchItem> items = googleSearchResponse.getItems();
        if (CollectionUtils.isEmpty(items)) {
            return null;
        }
        GoogleSearchItem googleSearchItem = items.get(0);
        return DEFAULT_SEARCH_MSG + googleSearchItem.getSnippet() + "来源网址：" + googleSearchItem.getDisplayLink();
    }

    @Override
    public String innerChat(String qa) {
        EmbeddingRequest request = EmbeddingRequest.builder()
                .model("text-embedding-ada-002")
                .input(Lists.newArrayList(qa)).build();
        EmbeddingResponse embeddings = openAiClient.embeddings(request);
        List<BigDecimal> embedding = embeddings.getData().get(0).getEmbedding();
        //去相似度最近的两条
        for (FileEmbedding fileEmbedding : FILE_EMBEDDING) {
            BigDecimal calculation = DistanceUtil.calculation(fileEmbedding.getEmbeddings(), embedding);
            fileEmbedding.setScore(calculation);
        }
        //安排距离排序
        List<FileEmbedding> sort = FILE_EMBEDDING.stream().sorted(Comparator.comparing(FileEmbedding::getScore).reversed())
                .collect(Collectors.toList());

        //取最新两个
        return MessageFormat.format(INNER_MSG, sort.get(0).getContent() + "\n" + sort.get(1).getContent());
    }

    private String parseUrl(String qa) {
        return "https://service-o91l4oi8-1300065309.usw.apigw.tencentcs.com/customsearch/v1?key=AIzaSyCbp1N1DJolF1sDnR-IZzKmfgsMnXFfRj8&start=0&num=1&cx=e20019ef2a80b4333&q=" + qa;
    }
}
